#!/usr/bin/env python
#
# helper.py - library module for pyinsim
#
# Copyright 2008-2012 Alex McBride <xandermcbride@gmail.com>
#
# This software may be used and distributed according to the terms of the
# GNU Lesser General Public License version 3 or any later version.
#

from re import compile
from math import sqrt


__all__ = ('degrees_radians', 'distance', 'intersects', 'length_km', 'length_metres', 'length_miles', 'metres_km', 'metres_miles', 'mps_kph', 'mps_mph', 'radians_degress', 'radians_rpm', 'speed_kph', 'speed_mph', 'speed_mps', 'strip_colours', 'time', 'timestr',)


# Constants.
_COLOUR_REGEX = compile('\^[0-9]')


# Functions.
def strip_colours(s):
    """Strip colour codes (^7, ^3 etc..) from a string.

    Args:
        s - the string to strip

    Return:
        The string sans-colours

    """
    return _COLOUR_REGEX.sub('', s)


def time(ms):
    """Convert milliseconds to hours, minutes, seconds, thousandths.

    Args:
        ms - the milliseconds to convert

    Return:
        a tuple containing the (hours, minutes, seconds, milliseconds)

    """
    return [int(ms / 3600000), 
            int(ms / 60000 % 60), 
            int(ms / 1000 % 60), 
            int(ms % 1000)]


def timestr(ms, hours=False):
    """Convert milliseconds to a formatted time str.

    Args:
        ms    - the milliseconds to convert
        hours - set True to include the hours component of the time

    Return:
        a formatted time string (e.g. 00:00:00.000)

    """
    h, m, s, t = time(ms)
    if h or hours:
        return '%d.%.2d:%.2d.%.3d' % (h, m, s, t)
    return '%d:%.2d.%.3d' % (m, s, t)


def speed_mps(speed):
    """Convert speed to metres per second.

    Args:
        speed - the speed to convert

    Returns:
        the speed as metres per second

    """
    return speed / 327.68


def speed_mph(speed):
    """Convert speed to miles per hour.

    Args:
        speed - the speed to convert

    Returns:
        the speed as miles per hour

    """
    return speed / 146.486067


def speed_kph(speed):
    """Convert speed to kilometres per hour.

    Args:
        speed - the speed to convert

    Returns:
        the speed as kilometres per hour

    """
    return speed / 91.02


def mps_mph(mps):
    """Convert metres per second to miles per hour.

    Args:
        mps - the metres per second to convert

    Returns:
        the mps as miles per hour

    """
    return mps * 2.23


def mps_kph(mps):
    """Convert metres per second to kilometres per hour.

    Args:
        mps - the metres per second to convert

    Returns:
        the mps as kilometres per hour

    """
    return mps * 3.6


def length_metres(length):
    """Convert a LFS world coordinate to metres.

    Args:
        length - the length as LFS world-coordinates

    Returns:
        the length in metres

    """
    return length / 65536.0


def length_miles(length):
    """Convert a LFS world coordinate to miles.

    Args:
        length - the length as LFS world-coordinates

    Returns:
        the length in miles

    """
    return length(length) / 1609.344


def length_km(length):
    """Convert a LFS world coordinate to kilometres.

    Args:
        length - the length as LFS world-coordinates

    Returns:
        the length in kilometres

    """
    return length(length) / 1000.0


def metres_miles(metres):
    """Convert metres to miles.

    Args:
        metres - the metres to convert

    Returns:
        the metres as miles

    """
    return metres / 1609.344


def metres_km(metres):
    """Convert metres to kilometres.

    Args:
        metres - the metres to convert

    Returns:
        the metres as kilometres

    """
    return metres / 1000.0


def radians_degress(radians):
    """Convert radians to degrees.

    Args:
        radians - the radians to convert

    Returns:
        the radians as degrees

    """
    return radians * 57.295773


def degrees_radians(degrees):
    """Convert degrees to radians.

    Args:
        degrees - the degreees to convert

    Returns:
        the degress as radians

    """
    return degrees * 0.017453


def radians_rpm(radians):
    """Convert radians to RPM.

    Args:
        radians - the radians to convert

    Returns:
        the radians as RPM

    """
    return radians * 9.549295


def distance(a=(0,0,0), b=(0,0,0)):
    """Determin the distance between two points.

    Args:
        a - a tuple containing the (x, y, z) coords
        b - a tuple containing the (x, y, z) coords

    Returns:
        the distance between the two points.

    """
    return sqrt((b[0] - a[0]) * (b[0] - a[0]) + (b[1] - a[1]) * (b[1] - a[1]) + (b[2] - a[2]) * (b[2] - a[2]))


def intersects(rect1=(0, 0, 0, 0), rect2=(0, 0, 0, 0)):
    """Determin if two rectangles intersect (top, left, width, height).

    Args:
        rect1 - a tuple containing the (left, top, width, height) of the first rectangle
        rect2 - a tuple containing the (left, top, width, height) of the second rectangle

    Returns:
        True if the two rectangles intersect

    """
    x1 = rect1[0] + rect1[2]
    y1 = rect1[1] + rect1[3]
    x3 = rect2[0] + rect2[2]
    y3 = rect2[1] + rect2[3]
    return not (x1 < rect2[0] or x3 < rect1[0] or y1 < rect2[1] or y3 < rect1[1])


if __name__ == '__main__':
    pass


